

/**************************************************START OF FILE*****************************************************/



/*------------------------------------------------------------------------------------------------------------------
Includes
*/
#include "main.h"
#include "usb_device.h"
#include "stm32f1xx_hal.h"
#include "xAPP_UsbAudio.h"
#include "xAPP_SingleData.h"
#include "xBSP_KeyScan.h"



/*------------------------------------------------------------------------------------------------------------------
Function
*/
void SystemClock_Config(void);
static void MX_GPIO_Init(void);
static void MX_SPI1_Init(void);
static void MX_SPI_DMA_Init(void);
void INT_Init(void);
static void MX_TIM2_Init(void);

void AudioTimeInit(void);

void xAPP_RunLedFlash(void);
void xAPP_RunLedPwm(void);
void xAPP_StatusLedFlash(void);
void xAPP_StatusLedPwm(void);

void xAPP_KeyScanTask(void);
void xAPP_SendFeedbackTask(void);


static void MX_TIM3_Init(void);



/*------------------------------------------------------------------------------------------------------------------
Variables
*/

//定时器句柄
TIM_HandleTypeDef htim2;
TIM_HandleTypeDef htim3;

//SPI DMA句柄
DMA_HandleTypeDef hdma_spi1_rx;
DMA_HandleTypeDef hdma_spi1_tx;

//SPI 句柄
SPI_HandleTypeDef hspi1;

extern uint32_t IIS_RX_Buffer[IIS_BUFFER_SIZE];
extern uint32_t IIS_TX_Buffer[IIS_BUFFER_SIZE];

//标记是否有录音跟播放的中断
uint32_t isPlayOrReco = 0;



/*
*********************************************************************************************************************

@ Brief  : 主函数

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:33

*********************************************************************************************************************
*/
int main(void)
{
	//HAL配置
	HAL_Init();

	//系统时钟配置
	SystemClock_Config();

	//产生一个正弦波信号
	xAPP_SIG_Init();

	//GPIO配置
	MX_GPIO_Init();

	//IIS配置 - 用SPI做IIS
	MX_SPI1_Init();
	MX_SPI_DMA_Init();

	//定时器配置，输出完成时钟同步
	MX_TIM2_Init();

	MX_TIM3_Init();

	while (1)
	{
		HAL_Delay(500);
		while(1)
		{
			if(TIM2->CNT < 1000 )
			{
				//启动DMA开始IIS收发数据
				HAL_SPI_TransmitReceive_DMA(&hspi1 ,(uint8_t*)IIS_TX_Buffer , (uint8_t*)IIS_RX_Buffer , IIS_BUFFER_SIZE * 2);
				break;
			}
		}

		while(1)
		{
			if(TIM2->CNT > 5000)
			{
				HAL_TIM_PWM_Stop(&htim2,TIM_CHANNEL_3);
				break;
			}
		}

		//USB设备初始化
		MX_USB_DEVICE_Init();

		//Audio辅助定时器
        AudioTimeInit();

		while(1)
		{
			//按键扫描
			xAPP_KeyScanTask();

			//运行状态的指示
			xAPP_RunLedFlash();
			
			//Status指示灯
			xAPP_StatusLedFlash();

			//USB Feedback
			xAPP_SendFeedbackTask();

		}
	}
}



/*
*********************************************************************************************************************
@ Brief  : 定时更新Feedback值任务

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-10-01 11:38
*********************************************************************************************************************
*/
extern void USBD_Audio_SendFeedback(void);
void xAPP_SendFeedbackTask(void)
{
	//10ms的按键接描任务
	static uint32_t CurrentTime = 0;
	static uint32_t LastTime = 0;
	CurrentTime = HAL_GetTick();
	if((CurrentTime - LastTime) > 10)
	{
		LastTime = CurrentTime;
		USBD_Audio_SendFeedback();
	}
}

/*
*********************************************************************************************************************
@ Brief  : 按键扫描任务

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-10-01 11:37
*********************************************************************************************************************
*/
void xAPP_KeyScanTask(void)
{
	//10ms的按键接描任务
	static uint32_t CurrentTime = 0;
	static uint32_t LastTime = 0;
	CurrentTime = HAL_GetTick();
	if((CurrentTime - LastTime) > 10)
	{
		LastTime = CurrentTime;
		xSYS_KEY_Scan();
	}
}


/*
*********************************************************************************************************************
@ Brief  : Run LED的闪烁

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-09-10 14:51
*********************************************************************************************************************
*/
void xAPP_RunLedFlash(void)
{
	static uint32_t CurrentTime = 0;
	static uint32_t LastTime = 0;
	CurrentTime = HAL_GetTick();
	if((CurrentTime - LastTime) > 5)
	{
		LastTime = CurrentTime;
		xAPP_RunLedPwm();
	}
}


/*
*********************************************************************************************************************
@ Brief  : 

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-09-12 22:56
*********************************************************************************************************************
*/
void xAPP_StatusLedFlash(void)
{
	static uint32_t CurrentTime = 0;
	static uint32_t LastTime = 0;
	CurrentTime = HAL_GetTick();
	if((CurrentTime - LastTime) > 5)
	{
		LastTime = CurrentTime;
		xAPP_StatusLedPwm();
	}
}



/*
*********************************************************************************************************************

@ Brief  : 系统时钟的配置

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:35

*********************************************************************************************************************
*/
void SystemClock_Config(void)
{
  RCC_OscInitTypeDef RCC_OscInitStruct = {0};
  RCC_ClkInitTypeDef RCC_ClkInitStruct = {0};
  RCC_PeriphCLKInitTypeDef PeriphClkInit = {0};

  /** Initializes the RCC Oscillators according to the specified parameters
  * in the RCC_OscInitTypeDef structure.
  */
  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE;
  RCC_OscInitStruct.HSEState = RCC_HSE_ON;
  RCC_OscInitStruct.HSEPredivValue = RCC_HSE_PREDIV_DIV1;
  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
  RCC_OscInitStruct.Prediv1Source = RCC_PREDIV1_SOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON;
  RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE;
  RCC_OscInitStruct.PLL.PLLMUL = RCC_PLL_MUL9;
  RCC_OscInitStruct.PLL2.PLL2State = RCC_PLL_NONE;
  if (HAL_RCC_OscConfig(&RCC_OscInitStruct) != HAL_OK)
  {
    Error_Handler();
  }
  /** Initializes the CPU, AHB and APB buses clocks
  */
  RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK
                              |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2;
  RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK;
  RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1;
  RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV2;
  RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1;

  if (HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_2) != HAL_OK)
  {
    Error_Handler();
  }
  PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB;
  PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_PLL_DIV3;
  if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
  {
    Error_Handler();
  }
  /** Configure the Systick interrupt time
  */
  __HAL_RCC_PLLI2S_ENABLE();
}

/*
*********************************************************************************************************************

@ Brief  : GPIO的配置

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:35

*********************************************************************************************************************
*/
static void MX_GPIO_Init(void)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	/* GPIO Ports Clock Enable */
	__HAL_RCC_GPIOD_CLK_ENABLE();
	__HAL_RCC_GPIOC_CLK_ENABLE();
	__HAL_RCC_GPIOA_CLK_ENABLE();
	__HAL_RCC_GPIOB_CLK_ENABLE();
	__HAL_RCC_SPI1_CLK_ENABLE();


    /**SPI1 GPIO Configuration    
    PA5     ------> SPI1_SCK
    PA6     ------> SPI1_MISO
    PA7     ------> SPI1_MOSI 
    */
    GPIO_InitStruct.Pin = GPIO_PIN_5|GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
    GPIO_InitStruct.Pin = GPIO_PIN_6;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	GPIO_InitStruct.Pin = GPIO_PIN_4;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);


	//KEY1-KEY6
	GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_3 | GPIO_PIN_4 | GPIO_PIN_5;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

	//LED灯 GPIO
	// GPIO_InitStruct.Pin = GPIO_PIN_0 | GPIO_PIN_1;
	// GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	// GPIO_InitStruct.Pull = GPIO_PULLUP;
	// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	// HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

}


/*
*********************************************************************************************************************
@ Brief  : 定时器3初始化

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-09-12 21:43
*********************************************************************************************************************
*/
static void MX_TIM3_Init(void)
{

	TIM_ClockConfigTypeDef sClockSourceConfig = {0};
	TIM_MasterConfigTypeDef sMasterConfig = {0};
	TIM_OC_InitTypeDef sConfigOC = {0};

	__HAL_RCC_TIM3_CLK_ENABLE();


	//定时器base配置
	htim3.Instance = TIM3;
	htim3.Init.Prescaler = 32-1;										//分频
	htim3.Init.CounterMode = TIM_COUNTERMODE_UP;						//向上计数
	htim3.Init.Period = 10000-1;											//				
	htim3.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	htim3.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_ENABLE;		//自动重装载
	if (HAL_TIM_Base_Init(&htim3) != HAL_OK)
	{
		while (1);
	}

	//时钟源配置
	sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
	if (HAL_TIM_ConfigClockSource(&htim3, &sClockSourceConfig) != HAL_OK)
	{
		while (1);
	}


	if (HAL_TIM_PWM_Init(&htim3) != HAL_OK)
	{
		while (1);
	}

	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
	sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
	if (HAL_TIMEx_MasterConfigSynchronization(&htim3, &sMasterConfig) != HAL_OK)
	{
		while (1);
	}


	sConfigOC.OCMode = TIM_OCMODE_PWM1;
	sConfigOC.Pulse = 0;	//PWM初始计数值  0/1000
	sConfigOC.OCPolarity = TIM_OCPOLARITY_LOW;
	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
	if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
	{
		while (1);
	}
	if (HAL_TIM_PWM_ConfigChannel(&htim3, &sConfigOC, TIM_CHANNEL_4) != HAL_OK)
	{
		while (1);
	}

	//GPIO的配置
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	__HAL_RCC_GPIOB_CLK_ENABLE();

    // PB0     ------> TIM3_CH3
    // PB1     ------> TIM3_CH4
    GPIO_InitStruct.Pin = GPIO_PIN_0|GPIO_PIN_1;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);


	__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_3 , 0);
	__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_4 , 0);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);

}


/*
*********************************************************************************************************************
@ Brief  : 

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-09-12 22:33
*********************************************************************************************************************
*/
void xAPP_RunLedPwm(void)
{
	static uint8_t TimeCount = 0;

	TimeCount++;
	if(TimeCount < 100)
	{
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_4 , TimeCount * 30);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
	}
	else
	{
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_4 , (200 - TimeCount) * 30);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_4);
	}

	if(TimeCount > 195)
	{
		TimeCount = 5;
	}
	

}



/*
*********************************************************************************************************************
@ Brief  : 

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2021-09-12 22:33
*********************************************************************************************************************
*/
void xAPP_StatusLedPwm(void)
{

	static uint8_t TimeCount = 0;

	if(isPlayOrReco == 0)
	{
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_3 , 0);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
		return;
	}
	isPlayOrReco = 0;

	TimeCount++;
	if(TimeCount < 100)
	{
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_3 , TimeCount * 30);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	}
	else
	{
		__HAL_TIM_SET_COMPARE(&htim3 , TIM_CHANNEL_3 , (200 - TimeCount) * 30);
		HAL_TIM_PWM_Start(&htim3,TIM_CHANNEL_3);
	}

	if(TimeCount > 195)
	{
		TimeCount = 5;
	}
}



/*
*********************************************************************************************************************

@ Brief  : SPI的配置

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:35

*********************************************************************************************************************
*/
static void MX_SPI1_Init(void)
{
	/* SPI1 parameter configuration*/
	hspi1.Instance = SPI1;
	hspi1.Init.Mode = SPI_MODE_SLAVE;
	hspi1.Init.Direction = SPI_DIRECTION_2LINES;
	hspi1.Init.DataSize = SPI_DATASIZE_16BIT;
	hspi1.Init.CLKPolarity = SPI_POLARITY_HIGH;
	hspi1.Init.CLKPhase = SPI_PHASE_2EDGE;
	hspi1.Init.NSS = SPI_NSS_HARD_INPUT;
	hspi1.Init.BaudRatePrescaler = SPI_BAUDRATEPRESCALER_4;
	hspi1.Init.FirstBit = SPI_FIRSTBIT_MSB;
	hspi1.Init.TIMode = SPI_TIMODE_DISABLE;
	hspi1.Init.CRCCalculation = SPI_CRCCALCULATION_DISABLE;
	hspi1.Init.CRCPolynomial = 10;
	if (HAL_SPI_Init(&hspi1) != HAL_OK)
	{
		while(1);
	}
}

/*
*********************************************************************************************************************

@ Brief  : SPI的DMA配置

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:36

*********************************************************************************************************************
*/
static void MX_SPI_DMA_Init(void)
{

	/* DMA controller clock enable */
	__HAL_RCC_DMA1_CLK_ENABLE();

	/* DMA interrupt init */
	/* DMA1_Channel2_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(DMA1_Channel2_IRQn, 1, 1);
	HAL_NVIC_EnableIRQ(DMA1_Channel2_IRQn);
	/* DMA1_Channel3_IRQn interrupt configuration */
	HAL_NVIC_SetPriority(DMA1_Channel3_IRQn, 1, 1);
	HAL_NVIC_EnableIRQ(DMA1_Channel3_IRQn);

		/* SPI1 DMA Init */
	/* SPI1_RX Init */
	hdma_spi1_rx.Instance = DMA1_Channel2;
	hdma_spi1_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
	hdma_spi1_rx.Init.PeriphInc = DMA_PINC_DISABLE;
	hdma_spi1_rx.Init.MemInc = DMA_MINC_ENABLE;
	hdma_spi1_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
	hdma_spi1_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
	hdma_spi1_rx.Init.Mode = DMA_CIRCULAR;
	hdma_spi1_rx.Init.Priority = DMA_PRIORITY_LOW;
	if (HAL_DMA_Init(&hdma_spi1_rx) != HAL_OK)
	{
		Error_Handler();
	}

	__HAL_LINKDMA(&hspi1,hdmarx,hdma_spi1_rx);

	/* SPI1_TX Init */
	hdma_spi1_tx.Instance = DMA1_Channel3;
	hdma_spi1_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
	hdma_spi1_tx.Init.PeriphInc = DMA_PINC_DISABLE;
	hdma_spi1_tx.Init.MemInc = DMA_MINC_ENABLE;
	hdma_spi1_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
	hdma_spi1_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
	hdma_spi1_tx.Init.Mode = DMA_CIRCULAR;
	hdma_spi1_tx.Init.Priority = DMA_PRIORITY_LOW;
	if (HAL_DMA_Init(&hdma_spi1_tx) != HAL_OK)
	{
		Error_Handler();
	}

	__HAL_LINKDMA(&hspi1,hdmatx,hdma_spi1_tx);


    __HAL_DMA_ENABLE_IT(&hdma_spi1_tx , DMA_IT_TC);
    __HAL_DMA_ENABLE_IT(&hdma_spi1_tx , DMA_IT_HT);
}





/*
*********************************************************************************************************************

@ Brief  : SPI 接收数据DMA中断

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:27

*********************************************************************************************************************
*/
void DMA1_Channel2_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_spi1_rx);

}

/*
*********************************************************************************************************************

@ Brief  : SPI 发送数据DMA中断

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 17:28

*********************************************************************************************************************
*/
void DMA1_Channel3_IRQHandler(void)
{
    HAL_DMA_IRQHandler(&hdma_spi1_tx);
}

/*
*********************************************************************************************************************

@ Brief  : 定时器2的配置，使用外部时钟，输了电平用于控制SPI CS的同步

@ Param  : NONE

@ Return : NONE

@ Author : YWJ(QQ:872180981)

@ Data   : 2020-06-15 10:33

*********************************************************************************************************************
*/

static void MX_TIM2_Init(void)
{
    //数据结构定义
    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};
    TIM_OC_InitTypeDef sConfigOC = {0};
    GPIO_InitTypeDef GPIO_InitStruct = {0};

	__HAL_RCC_TIM2_CLK_ENABLE();
    __HAL_RCC_GPIOA_CLK_ENABLE();

	//PA0 做为外部时钟输入
    GPIO_InitStruct.Pin = GPIO_PIN_0;
    GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
    GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	//输出，连接到SPI的CS
    GPIO_InitStruct.Pin = GPIO_PIN_2;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

	//IO配置复用
	__HAL_AFIO_REMAP_TIM2_DISABLE();


	htim2.Instance = TIM2;
	htim2.Init.Prescaler = 0;
	htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
	htim2.Init.Period = 10000;
	htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
	htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
	if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
	{
		Error_Handler();
	}
	sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_ETRMODE2;
	sClockSourceConfig.ClockPolarity = TIM_CLOCKPOLARITY_NONINVERTED;
	sClockSourceConfig.ClockPrescaler = TIM_CLOCKPRESCALER_DIV1;
	sClockSourceConfig.ClockFilter = 0;
	if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
	{
		Error_Handler();
	}
	if (HAL_TIM_PWM_Init(&htim2) != HAL_OK)
	{
		Error_Handler();
	}
	sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
	sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
	if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
	{
		Error_Handler();
	}
	sConfigOC.OCMode = TIM_OCMODE_PWM1;
	sConfigOC.Pulse = 0;
	sConfigOC.OCPolarity = TIM_OCPOLARITY_HIGH;
	sConfigOC.OCFastMode = TIM_OCFAST_DISABLE;
	if (HAL_TIM_PWM_ConfigChannel(&htim2, &sConfigOC, TIM_CHANNEL_3) != HAL_OK)
	{
		Error_Handler();
	}
	
	__HAL_TIM_SET_COMPARE(&htim2, TIM_CHANNEL_3, 5000);
	HAL_TIM_PWM_Start(&htim2,TIM_CHANNEL_3);
}



void AudioTimeInit(void)
{

    TIM_ClockConfigTypeDef sClockSourceConfig = {0};
    TIM_MasterConfigTypeDef sMasterConfig = {0};

    HAL_TIM_Base_DeInit(&htim2);

	__HAL_RCC_TIM2_CLK_ENABLE();

    htim2.Instance = TIM2;
    htim2.Init.Prescaler = 72 -1;
    htim2.Init.CounterMode = TIM_COUNTERMODE_UP;
    htim2.Init.Period = 0xFFFF;
    htim2.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1;
    htim2.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE;
    if (HAL_TIM_Base_Init(&htim2) != HAL_OK)
    {
        Error_Handler();
    }

    sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL;
  if (HAL_TIM_ConfigClockSource(&htim2, &sClockSourceConfig) != HAL_OK)
  {
    Error_Handler();
  }
  sMasterConfig.MasterOutputTrigger = TIM_TRGO_RESET;
  sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE;
  if (HAL_TIMEx_MasterConfigSynchronization(&htim2, &sMasterConfig) != HAL_OK)
  {
    Error_Handler();
  }

    HAL_TIM_Base_Start(&htim2);


    
}






/* USER CODE BEGIN 4 */

/* USER CODE END 4 */

/**
  * @brief  This function is executed in case of error occurrence.
  * @retval None
  */
void Error_Handler(void)
{
  /* USER CODE BEGIN Error_Handler_Debug */
  /* User can add his own implementation to report the HAL error return state */

  /* USER CODE END Error_Handler_Debug */
}

#ifdef  USE_FULL_ASSERT
/**
  * @brief  Reports the name of the source file and the source line number
  *         where the assert_param error has occurred.
  * @param  file: pointer to the source file name
  * @param  line: assert_param error line source number
  * @retval None
  */
void assert_failed(uint8_t *file, uint32_t line)
{ 
  /* USER CODE BEGIN 6 */
  /* User can add his own implementation to report the file name and line number,
     tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
  /* USER CODE END 6 */
}
#endif /* USE_FULL_ASSERT */



/**************************************************END OF FILE*******************************************************/
